import { sum, square } from '../uitl'

export function useSlideAction() {
	const origin = reactive({
		x: 0,
		y: 0
	})

	const success = ref(false)
	const isMouseDown = ref(false)
	const timestamp = ref(0)
	const trail = ref<number[]>([])

	const start = (e: MouseEvent | TouchEvent) => {
		if (success.value) return
		if (e instanceof MouseEvent) {
			origin.x = e.clientX
			origin.y = e.clientY
		} else {
			origin.x = e.changedTouches[0].pageX
			origin.y = e.changedTouches[0].pageY
		}
		isMouseDown.value = true
		timestamp.value = Date.now()
	}

	const move = (w: number, e: MouseEvent | TouchEvent, cb: (moveX: number) => void) => {
		if (!isMouseDown.value) return false
		let moveX = 0
		let moveY = 0
		if (e instanceof MouseEvent) {
			moveX = e.clientX - origin.x
			moveY = e.clientY - origin.y
		} else {
			moveX = e.changedTouches[0].pageX - origin.x
			moveY = e.changedTouches[0].pageY - origin.y
		}
		if (moveX < 0 || moveX + 38 >= w) return false
		cb(moveX)
		trail.value.push(moveY)
	}

	/**
	 * @param left : block.style.left;
	 * @param blockX
	 * @param accuracy
	 * @returns
	 */
	const verify = (left: string, blockX: number, accuracy: number) => {
		const arr = trail.value // drag y move distance
		const average = arr.reduce(sum) / arr.length // average
		const deviations = arr.map((x) => x - average) // deviation array
		const stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length) // standard deviation
		const leftNum = parseInt(left)
		accuracy = accuracy <= 1 ? 1 : accuracy > 10 ? 10 : accuracy
		return {
			spliced: Math.abs(leftNum - blockX) <= accuracy,
			TuringTest: average !== stddev // equal => not person operate
		}
	}

	const end = (e: MouseEvent | TouchEvent, cb: (timestamp: number) => void) => {
		if (!isMouseDown.value) return false
		isMouseDown.value = false
		const moveX = e instanceof MouseEvent ? e.clientX : e.changedTouches[0].pageX
		if (moveX === origin.x) return false
		timestamp.value = Date.now() - timestamp.value

		cb(timestamp.value)
	}

	return {
		origin,
		success,
		isMouseDown,
		timestamp,
		trail,
		start,
		move,
		end,
		verify
	}
}
